package com.blue.base.redis.aop;

import com.blue.base.redis.annotation.RedisLock;
import com.blue.base.redis.bean.LockTemplate;
import com.blue.base.redis.bean.RedisLockInfo;
import com.blue.base.redis.executors.LockKeyGenerator;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

/**
 * 分布式锁aop处理器
 *
 * @author liulei
 * @version 1.0
 */
@Slf4j
public class LockInterceptor implements MethodInterceptor {

    @Setter
    private LockTemplate lockTemplate;

    private LockKeyGenerator lockKeyGenerator = new LockKeyGenerator();

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        RedisLockInfo redisLockInfo = null;
        try {
            RedisLock lock = invocation.getMethod().getAnnotation(RedisLock.class);
            String keyName = lockKeyGenerator.getKeyName(invocation, lock);
            redisLockInfo = lockTemplate.lock(keyName, lock.expire(), lock.timeout());
            if (null != redisLockInfo) {
                return invocation.proceed();
            }
            // 没有获取到锁，根据个人习惯，抛出异常或者直接return掉
            return null;
        } finally {
            // 释放锁，保住在获取到锁之后，即使业务异常，也可以保证锁得到释放
            if (null != redisLockInfo) {
                lockTemplate.releaseLock(redisLockInfo);
            }
        }
    }

}
